#include <stdio.h>

/*
 * 在对象的多个实例之间共享虚函数表	P128
 * 
 * 无论对象可能存在多少个实例，所有这些实例都使用相同的虚函数表。
 * 
 * 虚函数属于对象，而不是属于这个对象的实例。
 */
class Base
{
	public:
		virtual void demo(void) {
			printf("Base demon\n");
		}
};

class Derived:public Base
{
	public:
		virtual void demo(void)
		{
			printf("Derived demo.\n");
		}
};

int main()
{
    Base *obj1 = new Derived;
	Base *obj2 = new Derived;

    obj1->demo();
	obj2->demo();

    return 0;
}

/*
	Derived demo.
	Derived demo.
 */

#if 0
/*
 * intel
 */
0000000000001169 <main>:
    1169:	f3 0f 1e fa          	endbr64 
    116d:	55                   	push   %rbp			// rsp-=8, (rsp)=rbp
    116e:	48 89 e5             	mov    %rsp,%rbp		// rbp=rsp
    1171:	53                   	push   %rbx			// rsp-=8, (rsp)=rbx
    1172:	48 83 ec 18          	sub    $0x18,%rsp		// rsp-=0x18
    1176:	bf 08 00 00 00       	mov    $0x8,%edi		// edi=0x8
    117b:	e8 e0 fe ff ff       	callq  1060 <_Znwm@plt>		// new(8)
    1180:	48 89 c3             	mov    %rax,%rbx		// rbx=rax=return value=this
    1183:	48 89 df             	mov    %rbx,%rdi		// rdi=rbx=this
    1186:	e8 ad 00 00 00       	callq  1238 <_ZN7DerivedC1Ev>	// Derived(rdi)
    118b:	48 89 5d e0          	mov    %rbx,-0x20(%rbp)		// rbp-0x20=rbx=this
    118f:	bf 08 00 00 00       	mov    $0x8,%edi		// edi=8
    1194:	e8 c7 fe ff ff       	callq  1060 <_Znwm@plt>		// new(8)
    1199:	48 89 c3             	mov    %rax,%rbx		// rbx=rax=return value=this
    119c:	48 89 df             	mov    %rbx,%rdi		// rdi=rbx=this
    119f:	e8 94 00 00 00       	callq  1238 <_ZN7DerivedC1Ev>	// Derived(rdi)
    11a4:	48 89 5d e8          	mov    %rbx,-0x18(%rbp)		// rbp-0x18=rbx=this
    11a8:	48 8b 45 e0          	mov    -0x20(%rbp),%rax		// rax=rbp-0x20
    11ac:	48 8b 00             	mov    (%rax),%rax		// rax=(rax)
    11af:	48 8b 10             	mov    (%rax),%rdx		// rdx=((rax))
    11b2:	48 8b 45 e0          	mov    -0x20(%rbp),%rax		// rax=rbp-0x20
    11b6:	48 89 c7             	mov    %rax,%rdi		// rdi=rax
    11b9:	ff d2                	callq  *%rdx			// rdx(rdi)
    11bb:	48 8b 45 e8          	mov    -0x18(%rbp),%rax		// rax=rbp-0x18=this
    11bf:	48 8b 00             	mov    (%rax),%rax		// rax=(rax)
    11c2:	48 8b 10             	mov    (%rax),%rdx		// rdx=((rax))
    11c5:	48 8b 45 e8          	mov    -0x18(%rbp),%rax		// rax=rbp-0x18
    11c9:	48 89 c7             	mov    %rax,%rdi		// rdi=rax
    11cc:	ff d2                	callq  *%rdx			// rdx(rdi)
    11ce:	b8 00 00 00 00       	mov    $0x0,%eax		// eax=0
    11d3:	48 83 c4 18          	add    $0x18,%rsp		// rsp+=0x18
    11d7:	5b                   	pop    %rbx			
    11d8:	5d                   	pop    %rbp
    11d9:	c3                   	retq   

00000000000011da <_ZN4Base4demoEv>:
    11da:	f3 0f 1e fa          	endbr64 
    11de:	55                   	push   %rbp
    11df:	48 89 e5             	mov    %rsp,%rbp
    11e2:	48 83 ec 10          	sub    $0x10,%rsp
    11e6:	48 89 7d f8          	mov    %rdi,-0x8(%rbp)
    11ea:	48 8d 3d 13 0e 00 00 	lea    0xe13(%rip),%rdi        # 2004 <_IO_stdin_used+0x4>
    11f1:	e8 7a fe ff ff       	callq  1070 <puts@plt>
    11f6:	90                   	nop
    11f7:	c9                   	leaveq 
    11f8:	c3                   	retq   
    11f9:	90                   	nop

00000000000011fa <_ZN7Derived4demoEv>:
    11fa:	f3 0f 1e fa          	endbr64 
    11fe:	55                   	push   %rbp
    11ff:	48 89 e5             	mov    %rsp,%rbp
    1202:	48 83 ec 10          	sub    $0x10,%rsp
    1206:	48 89 7d f8          	mov    %rdi,-0x8(%rbp)
    120a:	48 8d 3d fe 0d 00 00 	lea    0xdfe(%rip),%rdi        # 200f <_IO_stdin_used+0xf>
    1211:	e8 5a fe ff ff       	callq  1070 <puts@plt>
    1216:	90                   	nop
    1217:	c9                   	leaveq 
    1218:	c3                   	retq   
    1219:	90                   	nop

000000000000121a <_ZN4BaseC1Ev>:
    121a:	f3 0f 1e fa          	endbr64 
    121e:	55                   	push   %rbp
    121f:	48 89 e5             	mov    %rsp,%rbp
    1222:	48 89 7d f8          	mov    %rdi,-0x8(%rbp)
    1226:	48 8d 15 53 2b 00 00 	lea    0x2b53(%rip),%rdx        # 3d80 <_ZTV4Base+0x10>
    122d:	48 8b 45 f8          	mov    -0x8(%rbp),%rax
    1231:	48 89 10             	mov    %rdx,(%rax)
    1234:	90                   	nop
    1235:	5d                   	pop    %rbp
    1236:	c3                   	retq   
    1237:	90                   	nop

0000000000001238 <_ZN7DerivedC1Ev>:
    1238:	f3 0f 1e fa          	endbr64 
    123c:	55                   	push   %rbp
    123d:	48 89 e5             	mov    %rsp,%rbp
    1240:	48 83 ec 10          	sub    $0x10,%rsp
    1244:	48 89 7d f8          	mov    %rdi,-0x8(%rbp)
    1248:	48 8b 45 f8          	mov    -0x8(%rbp),%rax
    124c:	48 89 c7             	mov    %rax,%rdi
    124f:	e8 c6 ff ff ff       	callq  121a <_ZN4BaseC1Ev>
    1254:	48 8d 15 0d 2b 00 00 	lea    0x2b0d(%rip),%rdx        # 3d68 <_ZTV7Derived+0x10>
    125b:	48 8b 45 f8          	mov    -0x8(%rbp),%rax
    125f:	48 89 10             	mov    %rdx,(%rax)
    1262:	90                   	nop
    1263:	c9                   	leaveq 
    1264:	c3                   	retq   
    1265:	66 2e 0f 1f 84 00 00 	nopw   %cs:0x0(%rax,%rax,1)
    126c:	00 00 00 
    126f:	90                   	nop

/*
 * arm
 */
000000000040077c <main>:
  40077c:	a9bd7bfd 	stp	x29, x30, [sp, #-48]!
  400780:	910003fd 	mov	x29, sp
  400784:	f9000bf3 	str	x19, [sp, #16]			// sp+16=x19
  400788:	d2800100 	mov	x0, #0x8                   	// #8
  40078c:	97ffffb9 	bl	400670 <_Znwm@plt>		// new(8)
  400790:	aa0003f3 	mov	x19, x0				// x19=x0=return value=this
  400794:	aa1303e0 	mov	x0, x19				// x0=x19
  400798:	94000031 	bl	40085c <_ZN7DerivedC1Ev>	// Derived(x0)
  40079c:	f90017b3 	str	x19, [x29, #40]			// x29+40=x19=this
  4007a0:	d2800100 	mov	x0, #0x8                   	// #8
  4007a4:	97ffffb3 	bl	400670 <_Znwm@plt>		// new(8)
  4007a8:	aa0003f3 	mov	x19, x0				// x19=x0
  4007ac:	aa1303e0 	mov	x0, x19				// x0=x19
  4007b0:	9400002b 	bl	40085c <_ZN7DerivedC1Ev>	// Derived(x0)
  4007b4:	f90013b3 	str	x19, [x29, #32]			// x29+32=x19
  4007b8:	f94017a0 	ldr	x0, [x29, #40]			// x0=x29+40
  4007bc:	f9400000 	ldr	x0, [x0]			// x0=[x29+40]
  4007c0:	f9400001 	ldr	x1, [x0]			// x1=[[x29+40]]
  4007c4:	f94017a0 	ldr	x0, [x29, #40]			// x0=x29+40
  4007c8:	d63f0020 	blr	x1				// x1(x0)
  4007cc:	f94013a0 	ldr	x0, [x29, #32]			// x0=x28+32
  4007d0:	f9400000 	ldr	x0, [x0]			// x0=[x28+32]
  4007d4:	f9400001 	ldr	x1, [x0]			// x1=[[x28+32]]
  4007d8:	f94013a0 	ldr	x0, [x29, #32]			// x0=x29+32
  4007dc:	d63f0020 	blr	x1				// x1(x0)
  4007e0:	52800000 	mov	w0, #0x0                   	// #0
  4007e4:	f9400bf3 	ldr	x19, [sp, #16]
  4007e8:	a8c37bfd 	ldp	x29, x30, [sp], #48
  4007ec:	d65f03c0 	ret

00000000004007f0 <_ZN4Base4demoEv>:
  4007f0:	a9be7bfd 	stp	x29, x30, [sp, #-32]!
  4007f4:	910003fd 	mov	x29, sp
  4007f8:	f9000fa0 	str	x0, [x29, #24]
  4007fc:	90000000 	adrp	x0, 400000 <_init-0x5f8>
  400800:	91250000 	add	x0, x0, #0x940
  400804:	97ffff97 	bl	400660 <puts@plt>
  400808:	d503201f 	nop
  40080c:	a8c27bfd 	ldp	x29, x30, [sp], #32
  400810:	d65f03c0 	ret

0000000000400814 <_ZN7Derived4demoEv>:
  400814:	a9be7bfd 	stp	x29, x30, [sp, #-32]!
  400818:	910003fd 	mov	x29, sp
  40081c:	f9000fa0 	str	x0, [x29, #24]
  400820:	90000000 	adrp	x0, 400000 <_init-0x5f8>
  400824:	91254000 	add	x0, x0, #0x950
  400828:	97ffff8e 	bl	400660 <puts@plt>
  40082c:	d503201f 	nop
  400830:	a8c27bfd 	ldp	x29, x30, [sp], #32
  400834:	d65f03c0 	ret

0000000000400838 <_ZN4BaseC1Ev>:
  400838:	d10043ff 	sub	sp, sp, #0x10
  40083c:	f90007e0 	str	x0, [sp, #8]
  400840:	90000000 	adrp	x0, 400000 <_init-0x5f8>
  400844:	91262001 	add	x1, x0, #0x988
  400848:	f94007e0 	ldr	x0, [sp, #8]
  40084c:	f9000001 	str	x1, [x0]
  400850:	d503201f 	nop
  400854:	910043ff 	add	sp, sp, #0x10
  400858:	d65f03c0 	ret

000000000040085c <_ZN7DerivedC1Ev>:
  40085c:	a9be7bfd 	stp	x29, x30, [sp, #-32]!
  400860:	910003fd 	mov	x29, sp
  400864:	f9000fa0 	str	x0, [x29, #24]
  400868:	f9400fa0 	ldr	x0, [x29, #24]
  40086c:	97fffff3 	bl	400838 <_ZN4BaseC1Ev>
  400870:	90000000 	adrp	x0, 400000 <_init-0x5f8>
  400874:	9125c001 	add	x1, x0, #0x970
  400878:	f9400fa0 	ldr	x0, [x29, #24]
  40087c:	f9000001 	str	x1, [x0]
  400880:	d503201f 	nop
  400884:	a8c27bfd 	ldp	x29, x30, [sp], #32
  400888:	d65f03c0 	ret
  40088c:	00000000 	.inst	0x00000000 ; undefined


#endif
